﻿

using JinYuan.Helper;
using JinYuan.Models;
using Language;
using MiniExcelLibs;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace LargeSquareOne
{
    public partial class VariableEditForm : MultiLanguageForm
    {


        private string variableConfigPath = Application.StartupPath + "\\Config\\Variable.xlsx";
        private string groupConfigPath = Application.StartupPath + "\\Config\\Group.xlsx";
        private List<string> groupNames = new List<string>();

        private List<VariableConfig> Variables = new List<VariableConfig>();
        private VariableConfig editingConfig;
        private int PlcNum;

        public VariableEditForm(int plcNum)
        {
            PlcNum = plcNum;
            InitializeComponent();

            InitializeDataGridView();
            groupNames = GetGroupNames(PlcNum);
            Variables = GetALLVariables();
            LoadVariables();
        }

        private void InitializeDataGridView()
        {
            variableTable.AutoGenerateColumns = false;
            variableTable.AllowUserToAddRows = false;
            variableTable.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            variableTable.MultiSelect = false;
            variableTable.ReadOnly = false;

            // 添加列
            variableTable.Columns.AddRange(new DataGridViewColumn[]
            {
                new DataGridViewTextBoxColumn
            {
                Name = "PlcNum",
                HeaderText = "PLC编号",
                Width = 80,
                ReadOnly = true,
                DataPropertyName = "PlcNum"
            },
             new DataGridViewComboBoxColumn
            {
                Name = "GroupName",
                HeaderText = "组名",
                Width = 100,
                DataPropertyName = "GroupName",
                DataSource = new List<string>(groupNames), // 使用新列表避免引用问题
                ValueType = typeof(string),
                ReadOnly = false,
                DefaultCellStyle = new DataGridViewCellStyle
                {
                    BackColor = Color.FromArgb(14, 23, 38),  // 深色背景
                    ForeColor = Color.White,                  // 白色文字
                    SelectionBackColor = Color.FromArgb(0, 122, 204),  // 选中时的背景色
                    SelectionForeColor = Color.White,         // 选中时的文字颜色
                    Font = new Font("微软雅黑", 9F)           // 字体设置
                }
            },
            new DataGridViewTextBoxColumn
            {
                Name = "VarName",
                HeaderText = "变量名称",
                Width = 200,
                DataPropertyName = "VarName"
            },
            new DataGridViewTextBoxColumn
            {
                Name = "VarAddress",
                HeaderText = "变量地址",
                Width = 100,
                DataPropertyName = "VarAddress"
            },
            new DataGridViewTextBoxColumn
            {
                Name = "Start",
                HeaderText = "起始地址",
                Width = 100,
                DataPropertyName = "Start"
            },
            new DataGridViewComboBoxColumn
            {
                Name = "DataType",
                HeaderText = "数据类型",
                Width = 150,
                DataPropertyName = "DataType",
                Items = { "Short", "ByteArray" },
                DefaultCellStyle = new DataGridViewCellStyle
                {
                    BackColor = Color.FromArgb(14, 23, 38),  // 深色背景
                    ForeColor = Color.White,                  // 白色文字
                    SelectionBackColor = Color.FromArgb(0, 122, 204),  // 选中时的背景色
                    SelectionForeColor = Color.White,         // 选中时的文字颜色
                    Font = new Font("微软雅黑", 9F)           // 字体设置
                }
            },
            new DataGridViewTextBoxColumn
            {
                Name = "OffsetOrLength",
                HeaderText = "长度偏移",
                Width = 80,
                DataPropertyName = "OffsetOrLength"
            },

            new DataGridViewTextBoxColumn
            {
                Name = "Remark",
                HeaderText = "备注",
                Width = 120,
                DataPropertyName = "Remark",
                Visible = false
            },
            new DataGridViewButtonColumn
            {
                Name = "Edit",
                HeaderText = "操作",
                Width = 60,
                Text = "修改".Translated(),
                UseColumnTextForButtonValue = true
            },
            new DataGridViewButtonColumn
            {
                Name = "Delete",
                HeaderText = "",
                Width = 60,
                Text = "删除".Translated(),
                UseColumnTextForButtonValue = true
            }
            });

            // 添加事件处理
            variableTable.CellBeginEdit += DataGridView_CellBeginEdit;
            variableTable.CellEndEdit += DataGridView_CellEndEdit;
            variableTable.CellContentClick += DataGridView_CellContentClick;
            //variableTable.RowPostPaint += DataGridView_RowPostPaint;
        }


        // 添加此方法从 Group.xlsx 获取组名称
        private List<string> GetGroupNames(int plcNum)  // 添加 plcNum 参数
        {
            try
            {
                var groups = MiniExcel.Query<PlcGroupConfig>(groupConfigPath).ToList();
                // 根据 PLC 编号筛选，然后获取组名
                return groups.Where(g => g.PlcNum == plcNum)
                            .Select(g => g.GroupName)
                            .Distinct()
                            .ToList();
            }
            catch (Exception)
            {
                return new List<string> { "默认组".Translated() }; // 发生错误时返回默认组
            }
        }

        /// <summary>
        /// 获取所有通信组
        /// </summary>
        /// <returns></returns>
        private List<VariableConfig> GetALLVariables()
        {
            try
            {
                var variables = MiniExcel.Query<VariableConfig>(variableConfigPath).ToList();

                // 确保所有变量的组名都在groupNames列表中
                foreach (var variable in variables)
                {
                    if (!groupNames.Contains(variable.GroupName))
                    {
                        variable.GroupName = groupNames[0]; // 如果组名无效，使用第一个有效的组名
                    }
                }

                return variables;
            }
            catch (Exception)
            {
                return new List<VariableConfig>();
            }
        }


        private void LoadVariables()
        {
            try
            {
                var plcGroups = Variables.Where(g => g.PlcNum == PlcNum).ToList();

                // 在设置DataSource之前清除原有的绑定
                variableTable.DataSource = null;

                // 确保ComboBox列已经设置好数据源
                if (variableTable.Columns["GroupName"] is DataGridViewComboBoxColumn groupColumn)
                {
                    groupColumn.DataSource = new List<string>(groupNames);
                }

                // 设置新的数据源
                variableTable.DataSource = plcGroups;

                // 刷新表格
                variableTable.Refresh();
            }
            catch (Exception ex)
            {
                ShowError($"加载变量失败: {ex.Message}");
            }
        }


        private void DataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            if (e.RowIndex < 0) return;

            editingConfig = Variables[e.RowIndex];

            // 禁止编辑PLC编号和组名列
            if (variableTable.Columns[e.ColumnIndex].Name == "PlcNum")
            {
                e.Cancel = true;
            }
            //if (variableTable.Columns[e.ColumnIndex].Name == "PlcNum" ||
            //    variableTable.Columns[e.ColumnIndex].Name == "GroupName")
            //{
            //    e.Cancel = true;
            //}
        }

        private void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0 || e.RowIndex >= Variables.Count) return;

            var config = Variables[e.RowIndex];
            var value = variableTable[e.ColumnIndex, e.RowIndex].Value;

            try
            {
                UpdateConfigValue(config, variableTable.Columns[e.ColumnIndex].Name, value);
            }
            catch (Exception ex)
            {
                ShowError($"更新数据失败: {ex.Message}");
            }
        }

        private void UpdateConfigValue(VariableConfig config, string columnName, object value)
        {
            switch (columnName)
            {
                case "GroupName":
                    if (value != null && groupNames.Contains(value.ToString()))
                    {
                        config.GroupName = value.ToString();
                    }
                    else
                    {
                        throw new Exception("无效的组名".Translated());
                    }
                    break;

                case "VarName":
                    if (string.IsNullOrWhiteSpace(value?.ToString()))
                    {
                        throw new Exception("变量名不能为空".Translated());
                    }
                    if (Variables.Any(v => v != config &&
                        v.PlcNum == config.PlcNum &&
                        v.VarName.Equals(value.ToString(), StringComparison.OrdinalIgnoreCase)))
                    {
                        throw new Exception("变量名已存在".Translated());
                    }
                    config.VarName = value.ToString();
                    break;

                case "VarAddress":
                    if (!ValidateVariableAddress(value?.ToString()))
                    {
                        throw new Exception("地址格式不正确，应以'D'开头后跟数字".Translated());
                    }
                    if (columnName == "VarAddress")
                    {
                        config.VarAddress = value.ToString();
                    }

                    break;
                case "Start":
                    if (!ValidateStartAddress(value?.ToString()))
                    {
                        throw new Exception("地址格式不正确，应是纯数字".Translated());
                    }
                    if (columnName == "Start")
                    {
                        config.Start = value.ToString();
                    }

                    break;

                case "DataType":
                    if (!ValidateDataType(value?.ToString()))
                    {
                        throw new Exception("不支持的数据类型".Translated());
                    }
                    config.DataType = value.ToString();
                    break;

                case "OffsetOrLength":
                    if (!int.TryParse(value?.ToString(), out int length) || length <= 0)
                    {
                        throw new Exception("长度必须是大于0的数字".Translated());
                    }
                    config.OffsetOrLength = length;
                    break;

                case "Remark":
                    config.Remark = value?.ToString() ?? string.Empty;
                    break;
            }
        }

        private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0) return;

            // 获取当前行显示的数据
            var currentRow = variableTable.Rows[e.RowIndex];
            var config = (VariableConfig)currentRow.DataBoundItem;

            // 找到在 TotalGroups 中的真实索引
            var realIndex = Variables.FindIndex(g =>
                g.PlcNum == config.PlcNum &&
                g.GroupName == config.GroupName &&
                g.Start == config.Start);

            // 编辑按钮
            if (variableTable.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
                variableTable.Columns[e.ColumnIndex].Name == "Edit")
            {
                // 传递真实的索引，而不是显示的行索引
                HandleEdit(config, realIndex);
            }
            // 删除按钮
            else if (variableTable.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
                     variableTable.Columns[e.ColumnIndex].Name == "Delete")
            {
                HandleDelete(config);
            }
        }



        private void HandleEdit(VariableConfig config, int rowIndex)
        {
            try
            {
                var result = MessageBox.Show("是否保存修改的配置？".Translated(), "确认保存".Translated(), MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result != DialogResult.Yes) return;

                if (!ValidateConfigAll(config)) return;

                SaveConfigToExcel();
                LoadVariables();

                ShowSuccess("配置保存成功".Translated());
            }
            catch (Exception ex)
            {
                ShowError($"保存失败: {ex.Message}");
            }
        }

        private void HandleDelete(VariableConfig config)
        {
            var result = MessageBox.Show($"确定要删除该变量吗?\n PLC编号: [{config.PlcNum}],通信组: [{config.GroupName}],变量名: [{config.VarName}]", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
            {
                try
                {
                    Variables.Remove(config);
                    SaveConfigToExcel();
                    LoadVariables();
                    ShowSuccess("删除成功".Translated());
                }
                catch (Exception ex)
                {
                    ShowError($"删除失败: {ex.Message}");
                }
            }
        }

        private void SaveConfigToExcel()
        {
            try
            {
                string tempFilePath = Path.Combine(
                    Path.GetDirectoryName(variableConfigPath),
                    $"temp_{Path.GetFileName(variableConfigPath)}");

                // 先保存到临时文件
                MiniExcel.SaveAs(tempFilePath, Variables);

                if (!File.Exists(tempFilePath))
                {
                    throw new Exception("创建临时文件失败".Translated());
                }

                try
                {
                    if (File.Exists(variableConfigPath))
                    {
                        File.Delete(variableConfigPath);
                    }

                    File.Move(tempFilePath, variableConfigPath);
                }
                finally
                {
                    if (File.Exists(tempFilePath))
                    {
                        File.Delete(tempFilePath);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"保存Excel文件时发生错误: {ex.Message}", ex);
            }
        }

        private void BtnAdd_Click(object sender, EventArgs e)
        {
            try
            {
                // 确保有可用的组名
                if (groupNames == null || groupNames.Count == 0)
                {
                    ShowError("没有可用的组名，请先在Group.xlsx中添加组".Translated());
                    return;
                }

                string VarName = GenerateNewVarName();
                string VarAddress = FindNextAvailableAddress();


                var newVariable = new VariableConfig
                {
                    VarName = VarName,
                    VarAddress = VarAddress,
                    Start = VarAddress.Substring(1, VarAddress.Length - 1),
                    DataType = "Short",
                    OffsetOrLength = 1,
                    PlcNum = PlcNum,
                    GroupName = groupNames[0], // 使用第一个可用的组名
                    Remark = ""
                };

                if (!ValidateConfigAll(newVariable))
                {
                    return;
                }

                Variables.Add(newVariable);
                SaveConfigToExcel();
                LoadVariables();
                ShowSuccess("新建变量成功".Translated());
            }
            catch (Exception ex)
            {
                ShowError($"添加变量失败: {ex.Message}");
            }
        }


        private string GenerateNewVarName()
        {
            int index = 1;
            string baseName = "新变量".Translated();
            string newName = baseName;

            while (Variables.Any(v =>
                v.PlcNum == PlcNum &&
                v.VarName.Equals(newName, StringComparison.OrdinalIgnoreCase)))
            {
                index++;
                newName = $"{baseName}{index}";
            }

            return newName;
        }

        /// <summary>
        /// 获取地址
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private string FindNextAvailableAddress()
        {
            var plcVariables = Variables.Where(v => v.PlcNum == PlcNum).ToList();

            if (!plcVariables.Any())
            {
                return "D0";
            }

            int maxAddress = plcVariables.Max(v =>
            {
                int startAddr = int.Parse(v.VarAddress.Substring(1));
                return startAddr + v.OffsetOrLength;
            });

            if (maxAddress >= 32675)
            {
                throw new Exception("没有可用的地址空间".Translated());
            }

            return $"D{maxAddress}";
        }

        /// <summary>
        /// 验证变量配置
        /// </summary>
        private bool ValidateConfigAll(VariableConfig config)
        {
            try
            {
                // 基础验证
                if (string.IsNullOrWhiteSpace(config.VarName))
                {
                    ShowError("变量名不能为空".Translated());
                    return false;
                }

                if (!ValidateVariableAddress(config.VarAddress))
                {
                    ShowError("变量地址格式不正确".Translated());
                    return false;
                }

                if (!ValidateStartAddress(config.Start))
                {
                    ShowError("起始地址格式不正确".Translated());
                    return false;
                }

                if (!ValidateDataType(config.DataType))
                {
                    ShowError("不支持的数据类型".Translated());
                    return false;
                }

                if (config.OffsetOrLength <= 0)
                {
                    ShowError("长度必须大于0".Translated());
                    return false;
                }

                // 如果Variables为null，先初始化
                if (Variables == null)
                {
                    Variables = new List<VariableConfig>();
                    return true;
                }

                // 获取同一PLC的其他变量
                var otherVariables = Variables.Where(v => v != config && v.PlcNum == config.PlcNum).ToList();

                // 如果没有其他变量，则直接返回true
                if (!otherVariables.Any())
                {
                    return true;
                }

                // 检查重复
                if (otherVariables.Any(v => v.VarName.Equals(config.VarName, StringComparison.OrdinalIgnoreCase)))
                {
                    ShowError($"变量名 {config.VarName} 已存在");
                    return false;
                }

                if (otherVariables.Any(v => v.VarAddress.Equals(config.VarAddress, StringComparison.OrdinalIgnoreCase)))
                {
                    ShowError($"变量地址 {config.VarAddress} 已存在");
                    return false;
                }

                // 地址范围验证
                int startAddress;
                if (!int.TryParse(config.Start, out startAddress))
                {
                    ShowError("无效的起始地址".Translated());
                    return false;
                }

                int endAddress = startAddress + config.OffsetOrLength - 1;
                if (endAddress > 32767)
                {
                    ShowError($"地址范围超出限制,结束地址不能超过32767".Translated());
                    return false;
                }

                // 检查地址范围冲突
                foreach (var other in otherVariables)
                {
                    int otherStart;
                    if (!int.TryParse(other.Start, out otherStart))
                    {
                        continue;  // 跳过无效的地址
                    }

                    int otherEnd = otherStart + other.OffsetOrLength - 1;
                    if (!(endAddress < otherStart || startAddress > otherEnd))
                    {
                        ShowError($"地址范围与变量 \"{other.VarName}\" 冲突");
                        return false;
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                LogHelper.Instance.WriteError($"验证变量配置时发生错误: {ex}");  // 假设有日志记录器
                ShowError($"验证配置时发生错误,请检查输入是否正确".Translated());
                return false;
            }
        }


        /// <summary>
        /// 增强版的地址验证（支持多种地址格式）
        /// </summary>
        /// <param name="address">要验证的地址字符串</param>
        /// <returns>是否是有效的地址</returns>
        private bool ValidateVariableAddress(string address)
        {
            try
            {
                // 检查地址是否为空
                if (string.IsNullOrWhiteSpace(address))
                {
                    return false;
                }

                // 使用正则表达式匹配地址格式
                // 支持的格式：
                // D0-D32767
                // M0-M8191
                // DB1.DBX0.0
                // 等其他格式
                var pattern = @"^([DMdm]\d+|DB\d+\.DBX\d+\.\d+)$";
                if (!System.Text.RegularExpressions.Regex.IsMatch(address, pattern))
                {
                    return false;
                }

                // 根据不同地址类型进行验证
                if (address.StartsWith("D", StringComparison.OrdinalIgnoreCase))
                {
                    // D区地址验证
                    string numberPart = address.Substring(1);
                    if (!int.TryParse(numberPart, out int dAddress) || dAddress < 0 || dAddress > 32767)
                    {
                        return false;
                    }
                }
                else if (address.StartsWith("M", StringComparison.OrdinalIgnoreCase))
                {
                    // M区地址验证
                    string numberPart = address.Substring(1);
                    if (!int.TryParse(numberPart, out int mAddress) || mAddress < 0 || mAddress > 8191)
                    {
                        return false;
                    }
                }
                else if (address.StartsWith("DB", StringComparison.OrdinalIgnoreCase))
                {
                    // DB块地址验证
                    var parts = address.Split('.');
                    if (parts.Length != 3)
                    {
                        return false;
                    }

                    // 验证DB块号
                    string dbNumberPart = parts[0].Substring(2);
                    if (!int.TryParse(dbNumberPart, out int dbNumber) || dbNumber < 1 || dbNumber > 65535)
                    {
                        return false;
                    }

                    // 验证偏移地址
                    string offsetPart = parts[1].Substring(3);
                    if (!int.TryParse(offsetPart, out int offset) || offset < 0 || offset > 65535)
                    {
                        return false;
                    }

                    // 验证位地址
                    string bitPart = parts[2];
                    if (!int.TryParse(bitPart, out int bit) || bit < 0 || bit > 7)
                    {
                        return false;
                    }
                }

                return true;
            }
            catch
            {
                return false;
            }
        }


        /// <summary>
        /// 验证起始地址（纯数字格式）
        /// </summary>
        /// <param name="startAddress">要验证的起始地址字符串</param>
        /// <returns>是否是有效的起始地址</returns>
        private bool ValidateStartAddress(string startAddress)
        {
            try
            {
                // 检查地址是否为空
                if (string.IsNullOrWhiteSpace(startAddress))
                {
                    return false;
                }

                // 验证是否为纯数字
                if (!int.TryParse(startAddress, out int addressNum))
                {
                    return false;
                }

                // 检查地址范围（根据实际需求调整范围）
                if (addressNum < 0 || addressNum > 32767)
                {
                    return false;
                }

                return true;
            }
            catch
            {
                return false;
            }
        }


        /// <summary>
        /// 验证数据类型
        /// </summary>
        private bool ValidateDataType(string dataType)
        {
            if (string.IsNullOrWhiteSpace(dataType))
                return false;

            // 根据实际支持的数据类型列表进行验证
            string[] validTypes = new[] { "Bit", "Byte", "ByteArray", "Short", "Arrshort", "Word", "DWord", "Int", "DInt", "Real", "String" };
            return validTypes.Contains(dataType, StringComparer.OrdinalIgnoreCase);
        }



        private string FindAddressGap(int requiredLength = 1)
        {
            // 获取当前PLC的所有变量，并按起始地址排序
            var plcVariables = Variables
                .Where(v => v.PlcNum == PlcNum)
                .Select(v => new
                {
                    Start = int.Parse(v.VarAddress.Substring(1)),
                    End = int.Parse(v.VarAddress.Substring(1)) + v.OffsetOrLength - 1
                })
                .OrderBy(v => v.Start)
                .ToList();

            // 如果没有变量，返回起始地址
            if (!plcVariables.Any())
            {
                return "D0";
            }

            // 检查第一个变量之前是否有足够空间
            if (plcVariables.First().Start >= requiredLength)
            {
                return "D0";
            }

            // 检查变量之间的间隔
            for (int i = 0; i < plcVariables.Count - 1; i++)
            {
                int gapStart = plcVariables[i].End + 1;
                int gapEnd = plcVariables[i + 1].Start - 1;

                if (gapEnd - gapStart + 1 >= requiredLength)
                {
                    return $"D{gapStart}";
                }
            }

            // 检查最后一个变量之后是否有足够空间
            int lastEnd = plcVariables.Last().End;
            if (lastEnd + requiredLength <= 32675)
            {
                return $"D{lastEnd + 1}";
            }

            throw new Exception("没有找到足够大的地址空间".Translated());
        }

        // 错误提示
        private void ShowError(string message)
        {
            MessageBox.Show(message, "验证错误".Translated(), MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        // 成功提示
        private void ShowSuccess(string message)
        {
            MessageBox.Show(message, "成功".Translated(), MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btn_Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #region 减少闪烁
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }
        #endregion

        #region 无边框拖动
        private Point mPoint;
        private void Panel_MouseDown(object sender, MouseEventArgs e)
        {
            mPoint = new Point(e.X, e.Y);
        }

        private void Panel_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Location = new Point(this.Location.X + e.X - mPoint.X, this.Location.Y + e.Y - mPoint.Y);
            }
        }

        #endregion


    }
}
